home *** CD-ROM | disk | FTP | other *** search
/ Computer Shopper 242 / Issue 242 - April 2008 - DPCS0408DVD.ISO / Software Money Savers / VirtualDub / Source / VirtualDub-1.7.7-src.7z / src / Kasumi / source / blt.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2006-03-14  |  7.7 KB  |  260 lines

  1. #include <vector>
  2. #include <vd2/system/memory.h>
  3. #include <vd2/system/cpuaccel.h>
  4. #include <vd2/system/vdstl.h>
  5. #include <vd2/Kasumi/pixmap.h>
  6. #include <vd2/Kasumi/pixmaputils.h>
  7. #include <vd2/Kasumi/pixmapops.h>
  8.  
  9. using namespace nsVDPixmap;
  10.  
  11. namespace {
  12.     typedef void (*tpPalettedBlitter)(void *dst, ptrdiff_t dstpitch, const void *src, ptrdiff_t srcpitch, vdpixsize w, vdpixsize h, const void *pal);
  13.     typedef void (*tpChunkyBlitter)(void *dst, ptrdiff_t dstpitch, const void *src, ptrdiff_t srcpitch, vdpixsize w, vdpixsize h);
  14.     typedef void (*tpPlanarBlitter)(const VDPixmap& dst, const VDPixmap& src, vdpixsize w, vdpixsize h);
  15. }
  16.  
  17. bool VDPixmapBltDirect(const VDPixmap& dst, const VDPixmap& src, vdpixsize w, vdpixsize h);
  18.  
  19. void VDPixmapBltDirectPalettedConversion(const VDPixmap& dst, const VDPixmap& src, vdpixsize w, vdpixsize h, tpPalettedBlitter pBlitter) {
  20.     uint8 palbytes[256 * 3];
  21.  
  22.     int palsize;
  23.  
  24.     switch(src.format) {
  25.     case kPixFormat_Pal1:
  26.         palsize = 2;
  27.         break;
  28.     case kPixFormat_Pal2:
  29.         palsize = 4;
  30.         break;
  31.     case kPixFormat_Pal4:
  32.         palsize = 16;
  33.         break;
  34.     case kPixFormat_Pal8:
  35.         palsize = 256;
  36.         break;
  37.     default:
  38.         VDNEVERHERE;
  39.     }
  40.  
  41.     VDASSERT(src.palette);
  42.  
  43.     VDPixmap srcpal = { (void *)src.palette, NULL, palsize, 1, 0, kPixFormat_XRGB8888 };
  44.     VDPixmap dstpal = { palbytes, NULL, palsize, 1, 0, dst.format };
  45.  
  46.     VDVERIFY(VDPixmapBltDirect(dstpal, srcpal, palsize, 1));
  47.  
  48.     pBlitter(dst.data, dst.pitch, src.data, src.pitch, w, h, palbytes);
  49. }
  50.  
  51. tpVDPixBltTable VDPixmapGetBlitterTable() {
  52. #if defined(_WIN32) && defined(_M_IX86)
  53.     static tpVDPixBltTable pBltTable;
  54.     
  55.     if (CPUGetEnabledExtensions() & CPUF_SUPPORTS_MMX) {
  56.         return VDGetPixBltTableX86MMX();
  57.     } else {
  58.         return VDGetPixBltTableX86Scalar();
  59.     }
  60. #else
  61.     static tpVDPixBltTable pBltTable = VDGetPixBltTableReference();
  62.     return pBltTable;
  63. #endif
  64. }
  65.  
  66. bool VDPixmapBltDirect(const VDPixmap& dst, const VDPixmap& src, vdpixsize w, vdpixsize h) {
  67.     if ((unsigned)src.format >= kPixFormat_Max_Standard) {
  68.         VDASSERT(false);
  69.         return false;
  70.     }
  71.  
  72.     if ((unsigned)dst.format >= kPixFormat_Max_Standard) {
  73.         VDASSERT(false);
  74.         return false;
  75.     }
  76.  
  77.     const VDPixmapFormatInfo& srcinfo = VDPixmapGetInfo(src.format);
  78.  
  79.     if (src.format == dst.format) {
  80.         const int qw = -(-w >> srcinfo.qwbits);
  81.         const int qh = -(-h >> srcinfo.qhbits);
  82.         const int auxw = -(-w >> srcinfo.auxwbits);
  83.         const int auxh = -(-h >> srcinfo.auxhbits);
  84.  
  85.         switch(srcinfo.auxbufs) {
  86.         case 2:
  87.             VDMemcpyRect(dst.data3, dst.pitch3, src.data3, src.pitch3, auxw, auxh);
  88.         case 1:
  89.             VDMemcpyRect(dst.data2, dst.pitch2, src.data2, src.pitch2, auxw, auxh);
  90.         case 0:
  91.             VDMemcpyRect(dst.data, dst.pitch, src.data, src.pitch, srcinfo.qsize * qw, qh);
  92.         }
  93.  
  94.         return true;
  95.     }
  96.  
  97.     void *pBlitter = VDPixmapGetBlitterTable()[src.format][dst.format];
  98.  
  99.     if (!pBlitter)
  100.         return false;
  101.  
  102.     if (srcinfo.auxbufs > 0 || VDPixmapGetInfo(dst.format).auxbufs > 0) {
  103.         tpPlanarBlitter p = (tpPlanarBlitter)pBlitter;
  104.  
  105.         p(dst, src, w, h);
  106.     } else if (src.format == kPixFormat_Pal1 || src.format == kPixFormat_Pal2 || src.format == kPixFormat_Pal4 || src.format == kPixFormat_Pal8) {
  107.         tpPalettedBlitter p = (tpPalettedBlitter)pBlitter;
  108.  
  109.         if (dst.format == kPixFormat_XRGB8888)
  110.             p(dst.data, dst.pitch, src.data, src.pitch, w, h, src.palette);
  111.         else
  112.             VDPixmapBltDirectPalettedConversion(dst, src, w, h, p);
  113.     } else {
  114.         tpChunkyBlitter p = (tpChunkyBlitter)pBlitter;
  115.  
  116.         p(dst.data, dst.pitch, src.data, src.pitch, w, h);
  117.     }
  118.  
  119.     return true;
  120. }
  121.  
  122. bool VDPixmapIsBltPossible(int dst_format, int src_format) {
  123.     if (src_format == dst_format)
  124.         return true;
  125.  
  126.     tpVDPixBltTable tab(VDPixmapGetBlitterTable());
  127.  
  128.     if (tab[src_format][dst_format])
  129.         return true;
  130.  
  131.     const VDPixmapFormatInfo& srcinfo = VDPixmapGetInfo(src_format);
  132.     const VDPixmapFormatInfo& dstinfo = VDPixmapGetInfo(dst_format);
  133.  
  134.     if (srcinfo.auxbufs > 0 || dstinfo.auxbufs > 0)
  135.         return false;        // fail, planar buffers involved (can't do scanlines independently)
  136.  
  137.     return       (tab[src_format][kPixFormat_YUV444_XVYU] && tab[kPixFormat_YUV444_XVYU][dst_format])
  138.             ||(tab[src_format][kPixFormat_XRGB8888] && tab[kPixFormat_XRGB8888][dst_format]);
  139. }
  140.  
  141. bool VDPixmapBltFast(const VDPixmap& dst, const VDPixmap& src, vdpixsize w, vdpixsize h) {
  142.     if (VDPixmapBltDirect(dst, src, w, h))
  143.         return true;
  144.  
  145.     // Oro... let's see if we can do a two-stage conversion.
  146.     const VDPixmapFormatInfo& srcinfo = VDPixmapGetInfo(src.format);
  147.     const VDPixmapFormatInfo& dstinfo = VDPixmapGetInfo(dst.format);
  148.  
  149.     if (srcinfo.auxbufs > 0 || dstinfo.auxbufs > 0)
  150.         return false;        // fail, planar buffers involved
  151.  
  152.     if (srcinfo.qh > 1)
  153.         return false;        // fail, vertically packed formats involved
  154.  
  155.     if (srcinfo.palsize)
  156.         return false;        // fail, paletted formats involved
  157.  
  158.     // Allocate a 4xW buffer and try round-tripping through either
  159.     // RGB32 or XYVU.
  160.     vdblock<uint32>        tempBuf(w + 1);
  161.  
  162.     tpVDPixBltTable tab(VDPixmapGetBlitterTable());
  163.  
  164.     void *dstp = dst.data;
  165.     const void *srcp = src.data;
  166.  
  167.     tpChunkyBlitter pb1 = (tpChunkyBlitter)tab[src.format][kPixFormat_YUV444_XVYU];
  168.     tpChunkyBlitter pb2 = (tpChunkyBlitter)tab[kPixFormat_YUV444_XVYU][dst.format];
  169.     if (!pb1 || !pb2) {
  170.         pb1 = (tpChunkyBlitter)tab[src.format][kPixFormat_XRGB8888];
  171.         pb2 = (tpChunkyBlitter)tab[kPixFormat_XRGB8888][dst.format];
  172.         if (!pb1 || !pb2)
  173.             return false;
  174.     }
  175.  
  176.     do {
  177.         pb1(tempBuf.data(), 0, srcp, 0, w, 1);
  178.         pb2(dstp, 0, tempBuf.data(), 0, w, 1);
  179.         vdptrstep(srcp, src.pitch);
  180.         vdptrstep(dstp, dst.pitch);
  181.     } while(--h);
  182.     return true;
  183. }
  184.  
  185. bool VDPixmapBlt(const VDPixmap& dst, const VDPixmap& src) {
  186.     vdpixsize w = std::min<vdpixsize>(src.w, dst.w);
  187.     vdpixsize h = std::min<vdpixsize>(src.h, dst.h);
  188.  
  189.     if (!w || !h)
  190.         return true;
  191.  
  192.     return VDPixmapBltFast(dst, src, w, h);
  193. }
  194.  
  195. bool VDPixmapBlt(const VDPixmap& dst, vdpixpos x1, vdpixpos y1, const VDPixmap& src, vdpixpos x2, vdpixpos y2, vdpixsize w, vdpixsize h) {
  196.     if (x1 < 0) {
  197.         x2 -= x1;
  198.         w -= x1;
  199.         x1 = 0;
  200.     }
  201.  
  202.     if (y1 < 0) {
  203.         y2 -= y1;
  204.         h -= y1;
  205.         y1 = 0;
  206.     }
  207.  
  208.     if (x2 < 0) {
  209.         x1 -= x2;
  210.         w -= x2;
  211.         x2 = 0;
  212.     }
  213.  
  214.     if (y2 < 0) {
  215.         y1 -= y2;
  216.         h -= y2;
  217.         y2 = 0;
  218.     }
  219.  
  220.     if (w > dst.w - x1)
  221.         w = dst.w - x1;
  222.  
  223.     if (h > dst.h - y1)
  224.         h = dst.h - y1;
  225.  
  226.     if (w > src.w - x2)
  227.         w = src.w - x2;
  228.  
  229.     if (h > src.h - y2)
  230.         h = src.h - y2;
  231.  
  232.     if (w>=0 && h >= 0) {
  233.         VDPixmap dst2(VDPixmapOffset(dst, x1, y1));
  234.         VDPixmap src2(VDPixmapOffset(src, x2, y2));
  235.  
  236.         return VDPixmapBltFast(dst2, src2, w, h);
  237.     }
  238.  
  239.     return true;
  240. }
  241.  
  242. extern bool VDPixmapStretchBltNearest_reference(const VDPixmap& dst, sint32 x1, sint32 y1, sint32 x2, sint32 y2, const VDPixmap& src, sint32 u1, sint32 v1, sint32 u2, sint32 v2);
  243. extern bool VDPixmapStretchBltBilinear_reference(const VDPixmap& dst, sint32 x1, sint32 y1, sint32 x2, sint32 y2, const VDPixmap& src, sint32 u1, sint32 v1, sint32 u2, sint32 v2);
  244.  
  245. bool VDPixmapStretchBltNearest(const VDPixmap& dst, const VDPixmap& src) {
  246.     return VDPixmapStretchBltNearest(dst, 0, 0, dst.w<<16, dst.h<<16, src, 0, 0, src.w<<16, src.h<<16);
  247. }
  248.  
  249. bool VDPixmapStretchBltNearest(const VDPixmap& dst, sint32 x1, sint32 y1, sint32 x2, sint32 y2, const VDPixmap& src, sint32 u1, sint32 v1, sint32 u2, sint32 v2) {
  250.     return VDPixmapStretchBltNearest_reference(dst, x1, y1, x2, y2, src, u1, v1, u2, v2);
  251. }
  252.  
  253. bool VDPixmapStretchBltBilinear(const VDPixmap& dst, const VDPixmap& src) {
  254.     return VDPixmapStretchBltBilinear(dst, 0, 0, dst.w<<16, dst.h<<16, src, 0, 0, src.w<<16, src.h<<16);
  255. }
  256.  
  257. bool VDPixmapStretchBltBilinear(const VDPixmap& dst, sint32 x1, sint32 y1, sint32 x2, sint32 y2, const VDPixmap& src, sint32 u1, sint32 v1, sint32 u2, sint32 v2) {
  258.     return VDPixmapStretchBltBilinear_reference(dst, x1, y1, x2, y2, src, u1, v1, u2, v2);
  259. }
  260.